package service

import (
	"errors"

	"admin-system/internal/config"
	"admin-system/internal/model"
	"admin-system/pkg/hash"
	"gorm.io/gorm"
)

// UserService 用户服务
type UserService struct{}

// NewUserService 创建用户服务
func NewUserService() *UserService {
	return &UserService{}
}

// GetUserByID 根据ID获取用户
func (s *UserService) GetUserByID(id uint) (*model.User, error) {
	var user model.User
	err := config.DB.First(&user, id).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetUserByUsername 根据用户名获取用户
func (s *UserService) GetUserByUsername(username string) (*model.User, error) {
	var user model.User
	err := config.DB.Where("username = ?", username).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// CreateUser 创建用户
func (s *UserService) CreateUser(req *model.UserCreateRequest) (*model.User, error) {
	// 检查用户名是否已存在
	var count int64
	config.DB.Model(&model.User{}).Where("username = ?", req.Username).Count(&count)
	if count > 0 {
		return nil, errors.New("用户名已存在")
	}

	// 密码加密
	hashedPassword, err := hash.HashPassword(req.Password)
	if err != nil {
		return nil, err
	}

	// 创建用户
	user := model.User{
		Username: req.Username,
		Password: hashedPassword,
		Name:     req.Name,
		Email:    req.Email,
		Status:   req.Status,
	}

	// 使用事务确保用户和角色关系一起创建
	err = config.DB.Transaction(func(tx *gorm.DB) error {
		// 创建用户
		if err := tx.Create(&user).Error; err != nil {
			return err
		}

		// 分配角色
		if len(req.RoleIDs) > 0 {
			for _, roleID := range req.RoleIDs {
				userRole := model.UserRole{
					UserID: user.ID,
					RoleID: roleID,
				}
				if err := tx.Create(&userRole).Error; err != nil {
					return err
				}
			}
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &user, nil
}

// UpdateUser 更新用户
func (s *UserService) UpdateUser(id uint, req *model.UserUpdateRequest) error {
	// 检查用户是否存在
	var user model.User
	if err := config.DB.First(&user, id).Error; err != nil {
		return err
	}

	// 使用事务确保用户和角色关系一起更新
	return config.DB.Transaction(func(tx *gorm.DB) error {
		// 更新用户基本信息
		updates := map[string]interface{}{
			"name":   req.Name,
			"email":  req.Email,
			"status": req.Status,
		}
		if err := tx.Model(&user).Updates(updates).Error; err != nil {
			return err
		}

		// 更新角色关系
		if req.RoleIDs != nil {
			// 删除现有角色关系
			if err := tx.Where("user_id = ?", id).Delete(&model.UserRole{}).Error; err != nil {
				return err
			}

			// 添加新角色关系
			for _, roleID := range req.RoleIDs {
				userRole := model.UserRole{
					UserID: id,
					RoleID: roleID,
				}
				if err := tx.Create(&userRole).Error; err != nil {
					return err
				}
			}
		}

		return nil
	})
}

// DeleteUser 删除用户
func (s *UserService) DeleteUser(id uint) error {
	return config.DB.Transaction(func(tx *gorm.DB) error {
		// 删除用户角色关系
		if err := tx.Where("user_id = ?", id).Delete(&model.UserRole{}).Error; err != nil {
			return err
		}

		// 删除用户
		if err := tx.Delete(&model.User{}, id).Error; err != nil {
			return err
		}

		return nil
	})
}

// ListUsers 获取用户列表
func (s *UserService) ListUsers(page, pageSize int, keyword string) ([]model.User, int64, error) {
	var users []model.User
	var total int64

	query := config.DB.Model(&model.User{})

	// 关键字搜索
	if keyword != "" {
		query = query.Where("username LIKE ? OR name LIKE ? OR email LIKE ?",
			"%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Find(&users).Error; err != nil {
		return nil, 0, err
	}

	// 加载角色关系
	for i := range users {
		if err := config.DB.Model(&users[i]).Association("Roles").Find(&users[i].Roles); err != nil {
			return nil, 0, err
		}
	}

	return users, total, nil
}

// ChangePassword 修改密码
func (s *UserService) ChangePassword(id uint, oldPassword, newPassword string) error {
	// 获取用户
	var user model.User
	if err := config.DB.First(&user, id).Error; err != nil {
		return err
	}

	// 验证旧密码
	if !hash.CheckPassword(oldPassword, user.Password) {
		return errors.New("旧密码不正确")
	}

	// 加密新密码
	hashedPassword, err := hash.HashPassword(newPassword)
	if err != nil {
		return err
	}

	// 更新密码
	return config.DB.Model(&user).Update("password", hashedPassword).Error
}

// ResetPassword 重置密码
func (s *UserService) ResetPassword(id uint, newPassword string) error {
	// 获取用户
	var user model.User
	if err := config.DB.First(&user, id).Error; err != nil {
		return err
	}

	// 加密新密码
	hashedPassword, err := hash.HashPassword(newPassword)
	if err != nil {
		return err
	}

	// 更新密码
	return config.DB.Model(&user).Update("password", hashedPassword).Error
}
